using System;
using System.Collections.Generic;

namespace TAC {

	class Medio : InteligenciaArtificial {
		public readonly NonPlayerCharacter controlado;
		private List<ListaAtacantes> listaAtacantes;
		private Arena.MapaReal mapa;
		private int alvo;
		
		public Medio (NonPlayerCharacter control, Arena.MapaReal map) {
			controlado = control;
			listaAtacantes = new List<ListaAtacantes> ();
			mapa = map;
			alvo = 0;
		}
		
		/* FUNCOES */
		
		private static int comparaLista (ListaAtacantes um, ListaAtacantes dois) {
			int tmp = (um.personagem().getAttribute(ID.HEALTH) - um.personagem().getAttribute(ID.DAMAGE)) - (dois.personagem().getAttribute(ID.HEALTH) - dois.personagem().getAttribute(ID.DAMAGE));
			if (tmp != 0) {
				return tmp;
			} else {
				int tmp2 = um.personagem().getAttribute(ID.EXPERIENCE) - dois.personagem().getAttribute(ID.EXPERIENCE);
				if (tmp2 != 0) {
					return tmp2;
				} else {
					int tmp3 = um.ataques() - dois.ataques();
					if (tmp3 != 0) {
						return tmp3;
					} else {
						return (um.personagem().getAttribute(ID.TOTAL_POINTS) - dois.personagem().getAttribute(ID.TOTAL_POINTS));
					}
				}
			}
		}
		
		private void aoSerAtacado () {
			bool contido = false;
			int i;
			
			for (i = 0; i < listaAtacantes.Count; i++) {
				if (listaAtacantes[i].personagem() == controlado.getAttackedBy()) {
					contido = true;
					break;
				}
			}
			
			if (!contido) {
				listaAtacantes.Add (new ListaAtacantes (controlado.getAttackedBy()));
			} else {
				listaAtacantes[i].aumentaAtaque();
			}
			
			ListaAtacantes alvoX = listaAtacantes[alvo];
			
			listaAtacantes.Sort(comparaLista);
			
			alvo = listaAtacantes.BinarySearch(alvoX);
		}
		
		/* ACOES */
		
		private void atacar (ref Character alvoX) {
			if ((controlado.getAttribute(ID.DEXTERITY) - (controlado.getAttribute(ID.DEXTERITY)+4)/8) >= (controlado.getAttribute(ID.INTELLIGENCE) + 2*controlado.getAttribute(ID.INTELLIGENCE)/4 + controlado.getAttribute(ID.INTELLIGENCE)/8)) {
				controlado.BasicAttack(ref alvoX);
			} else {
				controlado.SpecialAttack(ref alvoX);
			}
		}
		
		private void perseguir (Character alvoX) {
			//TODO (pegar a posicao do alvoX no tabuleiro)
			//TODO (se nao tiver adjacente ao alvo)
				//TODO mover-se
			/*} else {
				atacar (alvoX);
			}*/
		}
		
	
		/* COMPORTAMENTO */
		
		public void comportamento () {
			if (listaAtacantes.Count > 0) {
				if (!listaAtacantes[alvo].personagem().isDead()) {
					perseguir(listaAtacantes[alvo].personagem());
				} else {
					listaAtacantes.RemoveAt(alvo);
					alvo = 0;
					perseguir(listaAtacantes[alvo].personagem());
				}
			} else {
				//Character maisProximo;
				//PEGAR O MAIS PROXIMO COM MENOS VIDA;
				//perseguir (maisProximo);
				//listaAtacantes.Add (new ListaAtacantes (maisProximo));
			}
		}
		
	}
}